package com.travelsky.app.util.system;

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import com.travelsky.app.Exception.BaseAppException;
import com.travelsky.app.util.validate.ValidateUtil;

public class ClientConnectControl
{
	protected static Logger log = Logger.getLogger(ClientConnectControl.class.getName());

	public static Map categoryConnectMaxCount = new HashMap<String,Integer>();  // 该类型最大可连接数
	public static Map categoryConnectcourrent = new HashMap<String,Integer>();  // 该类型当前实际连接数

	public static String OPT_TYPE_ADD = "OPT_ADD";
	public static String OPT_TYPE_SUB = "OPT_SUB"; 

	/**
	 * 通用类：用于控制不同类别的连接数量
	 * 可以在数据库中定义   AOC:5/FFP:10/CUSS:15
	 *                    类别：最大连接数
	 * 如果超过最大连接数，抛出异常
	 * @param category    类别
	 * @param optType     操作类型 OPT_TYPE_ADD：使用一条连接/OPT_TYPE_SUB：释放一条连接
	 * @throws Exception
	 */
	public static synchronized void operateLock(String category,String optType) throws Exception{
		if(categoryConnectcourrent == null || categoryConnectMaxCount == null || categoryConnectMaxCount.get(category) == null){
			log.error("[LOCK begin]" + category + ",opttype=" + optType + "系统初始化错误!");
			throw new BaseAppException("查询航班动态时出现异常，请稍后再试!");
		}

		//1、取得该类型最大可以连接数
		int maxNum = Integer.parseInt(categoryConnectMaxCount.get(category).toString());

		//2、取得该类型当前实际连接数
		int courrentConnectCount = 0;
		if(categoryConnectcourrent.get(category) != null){
			courrentConnectCount = Integer.parseInt(categoryConnectcourrent.get(category).toString());
		}  
		log.info("[LOCK Begin]" + category + ",opttype=" + optType + ",max=" + maxNum + ",current=" + courrentConnectCount);
		
		 
		//3、申请连接
		if (OPT_TYPE_ADD.equals(optType)){
			if (courrentConnectCount >= maxNum){
				log.error("系统繁忙，请稍候访问!");
				throw new BaseAppException("系统繁忙，请稍候访问!");
			}
			//增加一条连接
			courrentConnectCount++;
			categoryConnectcourrent.put(category, courrentConnectCount);
		}
		
		//4、释放连接
		if (OPT_TYPE_SUB.equals(optType)){
			if (courrentConnectCount <= 0){
				log.error("系统异常,the courrentConnectCount is <= 0 when you opt SUB"); 
			}else{
				//释放一条连接
				courrentConnectCount--;
				categoryConnectcourrent.put(category, courrentConnectCount);
			}
		}
		log.info("[LOCK end  ]" + category + ",opttype=" + optType + ",max=" + maxNum + ",current=" + courrentConnectCount);
	}  
	
	public static void initClientConnectControl(String configMsg){
		if(ValidateUtil.isBlank(configMsg)) return ;
		
		String[] configString = configMsg.split("/");
		if(configString == null || configString.length == 0) return;
		
		for(String oneconfig:configString){
			String[] msg = oneconfig.split(":");
			categoryConnectMaxCount.put(msg[0], msg[1]);			
		}
	}
	
	
	
	public static void main(String[] args){
		String configMsg = "AOC:5/FFP:10/CUSS:15";
		initClientConnectControl(configMsg); 
		try
		{ 
			ClientConnectControl.operateLock("AOC", ClientConnectControl.OPT_TYPE_ADD);
			ClientConnectControl.operateLock("FFP", ClientConnectControl.OPT_TYPE_SUB);
			ClientConnectControl.operateLock("AOC", ClientConnectControl.OPT_TYPE_SUB);
			ClientConnectControl.operateLock("FFP", ClientConnectControl.OPT_TYPE_ADD);
		}
		catch (Exception e)
		{ 
			e.printStackTrace();
		}		
	}
}
